using GamFi.Admin.API.Application.Exceptions;
using GamFi.Admin.API.Application.Resources;
using GamFi.Admin.API.Domain.Entities;
using MediatR;
using Microsoft.Extensions.Localization;
using MongoDB.Driver;

namespace GamFi.Admin.API.Application.Features.Queries.Chat.UpdateMessage;

/// <summary>
/// Обработчик команды на обновление сообщения в чате.
/// </summary>
public class UpdateMessageCommandHandler : IRequestHandler<UpdateMessageCommand, Unit>
{
    private readonly IMongoDatabase _database;
    private readonly IStringLocalizer<ExceptionMessages> _localizer;

    /// <summary>
    /// Конструктор обработчика команды на обновление сообщения в чате.
    /// </summary>
    /// <param name="database">Контекст базы данных.</param>
    /// <param name="localizer">Локализатор исключений.</param>
    public UpdateMessageCommandHandler(IMongoDatabase database, IStringLocalizer<ExceptionMessages> localizer)
    {
        _database = database;
        _localizer = localizer;
    }

    /// <summary>
    /// Обработка команды на обновление сообщения в чате.
    /// </summary>
    /// <param name="request">Команда на обновление сообщения.</param>
    /// <param name="cancellationToken">Токен для отмены операции.</param>
    /// <returns>Результат выполнения команды.</returns>
    public async Task<Unit> Handle(UpdateMessageCommand request, CancellationToken cancellationToken)
    {
        // Проверка на null-значение запроса
        if (request is null)
            throw new RequestException(_localizer[nameof(RequestException.RequestIsEmpty)]);

        // Получение коллекции сообщений из базы данных
        var messagesCollection = _database.GetCollection<Message>("Messages");

        // Поиск сообщения по идентификатору
        var filter = Builders<Message>.Filter.Eq("MessageId", request.MessageId);
        var existingMessage = await messagesCollection.Find(filter).FirstOrDefaultAsync(cancellationToken);

        // Проверка наличия сообщения
        if (existingMessage == null)
            throw new ChatException(_localizer[nameof(ChatException.MessageIsNotFound)]);

        // Обновление текста сообщения
        existingMessage.TextMessage = request.TextMessage;
        existingMessage.CreatedBy = request.CreatedBy.ToString();
        existingMessage.CreatedDate = request.CreatedDate;

        // Обновление сообщения в базе данных
        var updateResult = await messagesCollection.ReplaceOneAsync(
            Builders<Message>.Filter.Eq(m => m.Id, existingMessage.Id),
            existingMessage,
            new ReplaceOptions { IsUpsert = false }, // Ensure it's not an upsert
            cancellationToken);

        // Проверка успешности обновления
        if (updateResult.IsAcknowledged && updateResult.ModifiedCount > 0)
            // Возврат результата успешного выполнения
            return Unit.Value;
        // В случае неудачи выброс исключения
        throw new ChatException(_localizer[nameof(ChatException.MessageUpdateFailed)]);
    }
}